package cn.green.manage.service;

import cn.green.core.components.database.DBRouter;
import cn.green.core.executor.DmlExecutor;
import cn.green.manage.cache.QCache;
import cn.green.core.model.QField;
import cn.green.core.model.QTable;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * @author wang.yishu
 * @version 1.0
 * @className QDmlService
 * @description 数据库curd语言
 * @date 2025/1/16 13:47
 */
//done
@Transactional(readOnly = true)
public class QDmlService {

    protected QCache qCache;

    protected DmlExecutor dmlExecutor;

    protected DBRouter dbRouter;

    public QDmlService(QCache qCache, DmlExecutor dmlExecutor, DBRouter dbRouter) {
        this.qCache = qCache;
        this.dmlExecutor = dmlExecutor;
        this.dbRouter = dbRouter;
    }

    /**
     * 获取表信息
     * @param tableName 表名
     * @return 表信息
     */
    private QTable getTable(String source, String scheme, String tableName) {
        if (source == null || source.isEmpty()) {
            source = dbRouter.getMaster().getSourceName();
        }
        if (scheme == null || scheme.isEmpty()) {
            scheme = dbRouter.getMaster().getSchemeName();
        }
        QTable table = this.qCache.getTableFromCache(source, scheme, tableName);
        if (table == null) {
            throw new RuntimeException("QTable error: There is no table named [" + tableName + "] in System.");
        }
        List<QField> fields = this.qCache.getFieldsFromCache(source, scheme, tableName);
        table.setFields(fields);
        return table;
    }

    /**
     * 新增数据记录
     * @param tableName 表名
     * @param record    记录
     * @return 新增结果
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public Object istRecord(String source, String scheme, String tableName, JSONObject record) {
        if (source == null || source.isEmpty()) {
            source = dbRouter.getMaster().getSourceName();
        }
        if (scheme == null || scheme.isEmpty()) {
            scheme = dbRouter.getMaster().getSchemeName();
        }
        QTable table = this.getTable(source, scheme, tableName);
        if (record == null) {
            throw new RuntimeException("QTable error: record is null.");
        }
        if (table.getSchemeName() == null || table.getSchemeName().isEmpty()) {
            table.setSchemeName(dbRouter.getMaster().getSchemeName());
        }
        return this.dmlExecutor.insertRecord(table, record);
    }

    /**
     * 修改数据
     * @param tableName 表名
     * @param record    记录
     * @return 修改结果
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public Object uptRecord(String source, String scheme, String tableName, JSONObject record, String... conditions) {
        if (source == null || source.isEmpty()) {
            source = dbRouter.getMaster().getSourceName();
        }
        if (scheme == null || scheme.isEmpty()) {
            scheme = dbRouter.getMaster().getSchemeName();
        }
        QTable table = this.getTable(source, scheme, tableName);
        if (record == null) {
            throw new RuntimeException("QTable error: record is null.");
        }
        if (table.getSchemeName() == null || table.getSchemeName().isEmpty()) {
            table.setSchemeName(dbRouter.getMaster().getSchemeName());
        }
        return this.dmlExecutor.updateRecord(table, record, conditions);
    }

    /**
     * 删除数据
     * @param tableName 表名
     * @param record    记录
     * @return 删除结果
     */
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public Object delRecord(String source, String scheme, String tableName, JSONObject record, String... conditions) {
        if (scheme == null || scheme.isEmpty()) {
            scheme = dbRouter.getMaster().getSchemeName();
        }
        QTable table = this.getTable(source, scheme, tableName);
        if (record == null) {
            throw new RuntimeException("QTable error: record is null.");
        }
        if (table.getSchemeName() == null || table.getSchemeName().isEmpty()) {
            table.setSchemeName(dbRouter.getMaster().getSchemeName());
        }
        return this.dmlExecutor.deleteRecord(table, record, conditions);
    }
}
